/*
 * Copyrights 2015 Mars Don
 * All rights reserved.
 *
 */
#include <wmstdio.h>
#include <wm_os.h>
#include <wmtime.h>
#include <mdev_aes.h>

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

static os_thread_t lua_test_handle;
static os_thread_stack_define(lua_test_stack, 5120);

int32_t lua_main (void);
void lua_handler ( void* arg );

extern mdev_t *flash_drv_open(int fl_dev);
extern int flash_drv_read(mdev_t *dev, uint8_t *buf, uint32_t len, uint32_t addr);

int32_t lua_main(void)
{
	int32_t tc_state = 0;

	tc_state = os_thread_create( &lua_test_handle, "lua_test", lua_handler,
			0, &lua_test_stack, OS_PRIO_3);
	if( tc_state < 0 )
	{
#if CONFIG_DEBUG_OUTPUT
		wmprintf("Lua thread create error!\r\n");
#endif
		return -1;
	}

	return 0;
}

void lua_handler ( void* arg )
{
	int32_t i = 0, err = 0;
	uint8_t* p_lua_code = NULL;

	lua_State* p_l = NULL;
	mdev_t* fl_dev = NULL;

	fl_dev = flash_drv_open(0);
	if( fl_dev == NULL  )
	{
#if CONFIG_DEBUG_OUTPUT
		wmprintf("Flash driver init is required before open");
#endif
		err = -1;
	}
	else
	{// read lua file from flash 0xF1000
		p_lua_code = (uint8_t*)pvPortMalloc(8*1024);
		/* 5656 is lua file size for test */
		flash_drv_read(fl_dev, p_lua_code, 5656, 0xF1000);
#if CONFIG_DEBUG_OUTPUT
		wmprintf("lua flash read OK!\r\n");
#endif

		p_l = luaL_newstate();
#if CONFIG_DEBUG_OUTPUT
		wmprintf("lua new state\r\n");
#endif

		luaL_openlibs(p_l);
#if CONFIG_DEBUG_OUTPUT
		wmprintf("lua open libs\r\n");
#endif
		if( luaL_loadbuffer(p_l, (char*)p_lua_code, strlen((char*)p_lua_code), "broadlink") ||
				lua_pcall(p_l, 0, 0, 0) )
		{
			lua_pop(p_l, 1);
			lua_close(p_l);
			os_mem_free((char*)p_lua_code);
#if CONFIG_DEBUG_OUTPUT
			wmprintf("lua file is error\r\n");
#endif
			err = -1;
		}
#if CONFIG_DEBUG_OUTPUT
		else
			wmprintf("lua is ready\r\n");
#endif
		lua_getglobal(p_l, "rmac_information");
		if( lua_pcall(p_l, 0, 1, 0) != 0 )
		{
			const char* err_str = lua_tostring(p_l, -1);
#if CONFIG_DEBUG_OUTPUT
			wmprintf("Lua get info error:%s", err_str);
#endif
		}
		else
		{
			const char* dev_str = lua_tostring(p_l, -1);
#if CONFIG_DEBUG_OUTPUT
			wmprintf("dev info: %d, %s\r\n", strlen(dev_str), dev_str);
#endif
		}
		lua_pop(p_l, 1);
	}
	while ( err == 0 )
	{
		int32_t tab_tmp[200];
		int32_t tab_val = 0;

#if CONFIG_DEBUG_OUTPUT
		int32_t n_top = 0;

		n_top = lua_gettop(p_l);
		wmprintf("lua stack size is:%d\r\n", n_top);
#endif
		lua_getglobal(p_l, "rmac_output");
#if CONFIG_DEBUG_OUTPUT
		wmprintf("Lua get global\r\n");
#endif
		lua_pushnumber(p_l, 0);
		lua_pushnumber(p_l, 0);
		lua_pushnumber(p_l, 0);
		lua_pushnumber(p_l, 1);
		lua_pushnumber(p_l, 27);
		lua_pushnumber(p_l, 1);
		lua_pushnumber(p_l, 38);
#if CONFIG_DEBUG_OUTPUT
		wmprintf("Lua push number\r\n");
#endif
		if( lua_pcall(p_l, 7, 1, 0) != 0 )
		{
			const char* err_str = lua_tostring(p_l, -1);
			wmprintf("Lua call error: %s\r\n", err_str);
			lua_pop(p_l, 1);
		}
		else
		{
#if CONFIG_DEBUG_OUTPUT
			wmprintf("Lua call rmac_output\r\n");
#endif

			i = 0;
			lua_pushnil(p_l);
			while( lua_next(p_l, -2) )
			{
				if( i >= 300)
					break;
				tab_val = lua_tointeger(p_l, -1);
				tab_tmp[i++] = tab_val;
#if CONFIG_DEBUG_OUTPUT
				wmprintf("%d ", tab_tmp[i-1]);
#endif
				lua_pop(p_l, 1);
			}
			lua_pop(p_l, 1);
		}

		os_thread_sleep (2000);
	}

	// the code never be run into this place
	lua_close(p_l);
	os_mem_free(p_lua_code);
}

